package com.jeaven.instruction;

import com.jeaven.rtda.Frame;

public class invokevirtualInst implements Instruction {

//    public final String clazz;
//    public final String methodName;
//    public final String methodDescriptor;

//    public invokevirtualInst(String clazz, String methodName, String methodDescriptor) {
//        this.clazz = clazz;
//        this.methodName = methodName;
//        this.methodDescriptor = methodDescriptor;
//    }

    public invokevirtualInst() {

    }

    @Override
    public int offset() {
        return 3;
    }

    public void execute(Frame frame) {
       // todo
        System.out.println("operandStack 栈顶弹出元素为: " + frame.operandStack.popInt());
    }

    @Override
    public String debug(String prefix) {
        return "invokevirtual [Note]:invokevirtual还没有实现";
    }

    //    @Override
//    public void execute(Frame frame) {
//        KClass clazz = VirtualMachine.heap.findClass(this.clazz);
//        KMethod method = clazz.getMethod(methodName, methodDescriptor);
//
//        if (method == null) {
//            // try find interfaces
//            if (clazz.interfaceNames.isEmpty()) {
//                throw new IllegalStateException();
//            }
//
//            if (method == null) {
//                throw new IllegalStateException();
//            }
//
//            // super method
//            // fill args
//            List<String> args = method.getArgs();
//            List<Object> argObjs = new ArrayList<>();
//            for (int i = args.size() - 1; i >= 0; i--) {
//                String arg = args.get(i);
//                argObjs.add(Utils.pop(frame, arg));
//            }
//
//            KObject ref = (KObject) frame.operandStack.popRef();
//            KMethod implMethod = ref.clazz.getMethod(methodName, methodDescriptor);
//
//            NativeMethod nm = VirtualMachine.heap.findNativeMethod(Utils.generateNativeMethodKey(implMethod));
//            if (nm != null) {
//                // restore frame
//                ArrayList<String> tmpArgs = new ArrayList<>(args);
//                Collections.reverse(tmpArgs);
//
//                frame.operandStack.pushRef(ref);
//                for (int i = 0; i < tmpArgs.size(); i++) {
//                    String arg = tmpArgs.get(i);
//                    Object obj = argObjs.get(argObjs.size() - 1 - i);
//                    Utils.push(frame, arg, obj);
//                }
//
//                nm.invoke(frame);
//                return;
//            }
//
//            if (implMethod.isNative()) {
//                throw new IllegalStateException();
//            }
//
//            Collections.reverse(argObjs);
//
//            Frame newFrame = new Frame(implMethod, frame.thread);
//
//            int slotIdx = 1;
//            for (int i = 0; i < args.size(); i++) {
//                String arg = args.get(i);
//                slotIdx += Utils.setLocals(newFrame, slotIdx, arg, argObjs.get(i));
//            }
//
//            newFrame.setRef(0, ref);
//            frame.thread.pushFrame(newFrame);
//        }
//    }
}